package com.wikidot.designpatterns.composite.example1;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

/**
 *
 */
public abstract class AdministrativeUnit {
	// Logic for management of composite structure
	/** Name of this are. */
	protected String unitName;

	/** Link to parent area. */
	protected AdministrativeUnit parentUnit;
	/** List of child areas. */
	protected List<AdministrativeUnit> units;

	public AdministrativeUnit(String unitName, String locationCode) {
		this.unitName = unitName;
		this.locationCode = locationCode;
		this.units = new ArrayList<AdministrativeUnit>();
	}

	/**
	 * Indicates whether given area is composite structure or leaf.
	 * 
	 * @return <code>true</code> if given area has at least one sub area.
	 */
	public final boolean isComposite() {
		return !this.units.isEmpty();
	}

	/**
	 * Add unit into composite.
	 * 
	 * @param unit
	 *            Child unit.
	 */
	public final void addUnit(AdministrativeUnit unit) {
		unit.parentUnit = this;
		this.units.add(unit);
	}

	/**
	 * Remove unit from composite. If the last child unit is removed, given node
	 * becomes leaf.
	 * 
	 * @param unit
	 *            Unit to be removed.
	 */
	public final void removeUnit(AdministrativeUnit unit) {
		this.units.remove(unit);
	}

	/**
	 * List recursively all children of this unit.
	 * 
	 * @return Iterable structure over child units.
	 */
	public final ListIterator<AdministrativeUnit> listUnits() {
		return this.units.listIterator();
	}

	// Business logic - abstract; each concrete implementation defines own rules
	protected String locationCode;

	/**
	 * The business logic methods are in general abstract. The behavior is
	 * dependent on concrete implementation, whether it is intermediate node or
	 * leaf in composite tree structure.
	 * 
	 * This business method provides functionality of reporting staffing
	 * information for every organizational unit.
	 * 
	 * @return TODO
	 */
	public abstract String getLocationInformation();
	

	public abstract String unitNameLabel();

}
